package imai78gae.heya.action;

import imai78gae.heya.HeyaConstants;
import imai78gae.heya.exception.ResourceNotFoundException;
import imai78gae.heya.guice.HeyaModule;
import imai78gae.heya.model.UserInfo;
import imai78gae.heya.service.AccountService;

import javax.servlet.http.HttpServletRequest;

import org.seasar.cubby.action.Accept;
import org.seasar.cubby.action.ActionClass;
import org.seasar.cubby.action.ActionResult;
import org.seasar.cubby.action.FlashMap;
import org.seasar.cubby.action.Forward;
import org.seasar.cubby.action.Path;
import org.seasar.cubby.action.Redirect;
import org.seasar.cubby.action.RequestMethod;
import org.seasar.cubby.action.RequestParameter;
import org.seasar.cubby.action.Validation;
import org.seasar.cubby.validator.DefaultValidationRules;
import org.seasar.cubby.validator.ValidationRules;
import org.seasar.cubby.validator.validators.MaxLengthValidator;
import org.seasar.cubby.validator.validators.RegexpValidator;
import org.seasar.cubby.validator.validators.RequiredValidator;

import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.servlet.RequestScoped;

/**
 * トップにアクセスされた際の{@code Action}クラスです。
 * 
 * @author imai78
 *
 */
@RequestScoped
@ActionClass
@Path("/")
public class IndexAction {

	/**
	 * トップ画面に対する入力検査仕様です。
	 */
	ValidationRules validation = new DefaultValidationRules() {
		@Override
		public void initialize() {
			// ログインID
			super.add("uid", new RequiredValidator(),
					new MaxLengthValidator(20),
					new RegexpValidator("[0-9a-zA-Z]+"));
			// パスワード
			super.add("upw", new RequiredValidator(),
					new MaxLengthValidator(20),
					new RegexpValidator("[0-9a-zA-Z]+"));
		}
	};

	/**
	 * 入力されるログインIDです。
	 */
	@RequestParameter
	public String uid;

	/**
	 * 入力されるパスワードです。
	 */
	@RequestParameter
	public String upw;

	/**
	 * トップで使用する{@link FlashMap}です。
	 */
	@Inject
	private FlashMap flashMap;

	/**
	 * {@code Session}を操作する為の{@link HttpServletRequest}です。
	 * TODO もっと効率の良い方法があるようにも思うが。。。
	 */
	@Inject
	public HttpServletRequest request;

	/**
	 * トップの画面で使用する{@link AccountService}です。
	 */
	private AccountService accountService = Guice.createInjector(
			new HeyaModule()).getInstance(AccountService.class);

	/**
	 * 最初にアクセスされた際のアクション・メソッドです。
	 * 
	 * @return {@code /b/index.jsp}
	 * @throws Exception
	 */
	@Accept(RequestMethod.GET)
	public ActionResult index() throws Exception {
		return new Forward("b/index.jsp");
	}

	/**
	 * ログインボタンが押された際のアクション・メソッドです。
	 * <p>
	 * このメソッドが実行された時点で、フィールド{@code uid}と{@code upw}に
	 * 入力されたログインID、パスワードが設定されています。
	 * </p>
	 * 
	 * @return {@code /b/entrance.jsp}
	 * @throws Exception
	 */
	@Accept(RequestMethod.POST)
	@Validation(rules = "validation", errorPage = "b/index.jsp")
	public ActionResult login() throws Exception {
		try {
			String loginId = this.uid.trim();
			String loginPw = this.upw.trim();
			UserInfo user = this.accountService.login(loginId, loginPw);
			// セッションに格納。
			this.request.getSession().setAttribute(HeyaConstants.SESSION_KEY.USER, user);
			return new Redirect("entrance/");
		} catch (ResourceNotFoundException e) {
			this.flashMap.put("notice", "入力されたアカウントは登録されていないようです。");
			return new Redirect("./");
		}
	}

}
